package com.zmzncs.lmtc.module.order.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmzncs.lmtc.common.interactive.mp.MpMessage;
import com.zmzncs.lmtc.common.util.WeChatUtil;
import com.zmzncs.lmtc.common.pojo.enums.optionalvalue.order.OrderRefundStatusEnum;
import com.zmzncs.lmtc.common.pojo.mpMessage.RefundFalse;
import com.zmzncs.lmtc.common.pojo.mpMessage.RefundSuccess;
import com.zmzncs.lmtc.common.util.*;
import com.zmzncs.lmtc.module.customer.dao.CardRecordDao;
import com.zmzncs.lmtc.module.customer.pojo.card_record.CardRecord;
import com.zmzncs.lmtc.module.customer.pojo.card_record.CardRecordDTO;
import com.zmzncs.lmtc.module.customer.pojo.cust_info.CustInfo;
import com.zmzncs.lmtc.module.customer.service.CustInfoService;
import com.zmzncs.lmtc.module.order.dao.OrderInfoDao;
import com.zmzncs.lmtc.module.order.dao.OrderRefundMapper;
import com.zmzncs.lmtc.module.order.pojo.order_Info.OrderInfo;
import com.zmzncs.lmtc.module.order.pojo.order_refund.OrderRefund;
import com.zmzncs.lmtc.module.order.pojo.order_refund.OrderRefundAuditForm;
import com.zmzncs.lmtc.module.order.pojo.order_refund.OrderRefundDTO;
import com.zmzncs.lmtc.module.order.service.OrderRefundService;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.dao.ReserveRecordDao;
import com.zmzncs.lmtc.module.park.pojo.park_info.ParkInfo;
import com.zmzncs.lmtc.module.park.pojo.reserve_record.ReserveRecordDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;

/**
 * <p>
 * 订单-退款 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-10-21
 */
@Slf4j
@Service
public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, OrderRefund> implements OrderRefundService {

    @Autowired
    OrderRefundMapper orderRefundMapper;
    @Autowired
    CardRecordDao cardRecordDao;
    @Autowired
    OrderInfoDao orderInfoDao;
    @Autowired
    CustInfoService custInfoService;
    @Autowired
    MpMessage mpMessage;
    @Autowired
    ReserveRecordDao reserveRecordDao;
    @Autowired
    ParkInfoDao parkInfoDao;

    @Value("${file-url-prefix}")
    private String fileUrlPrefix;

    /**
     * 获取退款列表
     */
    @Override
    public IPage<OrderRefundDTO> getRefundList(Page page) {
        IPage<OrderRefundDTO> refundPage = orderRefundMapper.getRefundList(page);
        for(OrderRefundDTO orderRefundDTO: refundPage.getRecords()){
            //  获取进出场订单
            OrderInfo orderInfo = orderInfoDao.selectByOrderCode(orderRefundDTO.getOrderCode());
            //  客户
            CustInfo custInfo = custInfoService.getById(orderRefundDTO.getCustomerId());

            if(custInfo != null){
                orderRefundDTO.setUsername(custInfo.getNickname());
                orderRefundDTO.setTelephone(custInfo.getMobilePhone());
            }
            if(orderInfo != null){
                orderRefundDTO.setCarNum(orderInfo.getCarNumber());
                orderRefundDTO.setInTime(orderInfo.getInTime());
                orderRefundDTO.setOutTime(orderInfo.getOutTime());
                //  停车场
                ParkInfo parkInfo = parkInfoDao.selectById(orderInfo.getParkId());
                if(parkInfo != null){
                    orderRefundDTO.setParkName(parkInfo.getParkName());
                }
            }
        }

        return refundPage;
    }

    /**
     * 审核退款
     */
    @Override
    @Transactional
    public void auditRefund(OrderRefundAuditForm form) {
        //  获取退款申请详情
        OrderRefund orderRefund = orderRefundMapper.selectById(form.getRefundId());
        //  获取进出场订单
        OrderInfo orderInfo = orderInfoDao.selectByOrderCode(orderRefund.getOrderCode());
        if (orderInfo == null) {
            ExceptionUtil.businessException("订单不存在");
        }
        //  客户
        CustInfo custInfo = custInfoService.getById(orderInfo.getCustomerId());
        //  微信支付交易记录
        CardRecordDTO cardRecordDTO = cardRecordDao.getByOrderCode(orderRefund.getCardRecordOrderCode());

        orderRefund.setRemark(form.getRemark());    //  评论
        orderRefund.setStatus(form.getStatus().getCode());  //  审核状态

        //  审核通过
        if (form.getStatus().equals(OrderRefundStatusEnum.APPROVED)) {
            //  可退款支付订单
            boolean flag = false;
            //  微信退款申请
            String tradeNo = WeChatUtil.generateTradeNo();
            BigDecimal refundAmount = orderRefund.getRefundAmount();
            BigDecimal refundFee = form.getRefundFee();
            String cardRecordOrderCode = orderRefund.getCardRecordOrderCode();
            String reason = orderRefund.getReason();
            Map result = WeChatUtil.refund(tradeNo,refundAmount, refundFee,cardRecordOrderCode,reason );
            if ("SUCCESS".equals(result.get("result_code"))) {
                //  记录退款的会员卡支付记录
                CardRecord cardRecord = new CardRecord();
                cardRecord.setId(cardRecordDTO.getId());
                cardRecord.setRefundAmount(form.getRefundFee());
                cardRecordDao.updateById(cardRecord);

                //  设置退款信息
                orderRefund.setTradeNo(tradeNo);
                orderRefund.setRefundAmount(form.getRefundFee());
                //退款成功微信公众号信息
                if (custInfo != null && custInfo.getUnionid() != null) {
                    RefundSuccess message = new RefundSuccess();
                    message.setUnionid(custInfo.getUnionid());
                    message.setRefundCode(orderRefund.getOrderCode());
                    message.setRefundFee(orderRefund.getRefundAmount().toString());
                    //退款成功通知
                    mpMessage.refundSuccessMessage(message);
                }
            } else {
                String resultStr = "退款失败";
                Object err_code_des = result.get("err_code_des");
                if (err_code_des != null){
                    resultStr = resultStr + err_code_des.toString();
                }
                Object return_msg = result.get("return_msg");
                if ( return_msg != null){
                    resultStr = resultStr + return_msg.toString();
                }

                ExceptionUtil.businessException(resultStr);
            }
        //  拒绝退款微信公众号信息
        } else {
            try {
                if (custInfo != null && custInfo.getUnionid() != null) {
                    if (orderRefund.getStatus() == 3) {
                        RefundFalse message = new RefundFalse();
                        message.setUnionid(custInfo.getUnionid());
                        message.setRefundCode(orderRefund.getOrderCode());
                        message.setRefundFee(orderRefund.getRefundAmount().toString());
                        message.setApplyTime(DateTimeUtil.convertYMDHMS(orderRefund.getCreateTime()));
                        message.setRemark(orderRefund.getRemark());
                        //拒绝退款通知
                        mpMessage.refundFalseMessage(message);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //  修改退款订单状态
        orderRefundMapper.updateById(orderRefund);
    }

    @Override
    public String reserveRefund(String orderCode) {

        String rest = "预约退款失败";

        ReserveRecordDTO reserveRecord = reserveRecordDao.getReserveRecordByOrderCode(orderCode);
        if (reserveRecord != null){

            //  微信退款申请
            String tradeNo = WeChatUtil.generateTradeNo();
            Map result = WeChatUtil.refund(tradeNo, reserveRecord.getReserveAmount(), reserveRecord.getReserveAmount(),
                    orderCode, "预约退款");
            if (result != null && result.get("resultCode").equals("SUCCESS")) {
                rest = "预约退款成功";
                CustInfo custInfo = custInfoService.getById(reserveRecord.getCustomerId());
                //退款成功微信公众号信息
                if (custInfo != null && custInfo.getUnionid() != null) {
                    RefundSuccess message = new RefundSuccess();
                    message.setUnionid(custInfo.getUnionid());
                    message.setRefundCode(orderCode);
                    message.setRefundFee(reserveRecord.getReserveAmount().toString());
                    //退款成功通知
                    mpMessage.refundSuccessMessage(message);
                }
            }
        }
        return rest;
    }

}
